﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Clean
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                foreach (var file in openFileDialog1.FileNames)
                {

                    var b = new List<string>();
                    var d = new List<List<float>>();
                    var suml = new List<float>();
                    var temp = new UTF8Encoding(true);

                    b = File.ReadAllLines(file).ToList();
                
                    double t = Convert.ToDouble(textBox36.Text);

                    //  Parallel.For(0, date.Count - 2, i =>
                    for (var i = 1; i < b.Count ; i += 2)
                    {
                        double tempd = 0;
                        var s = b[i].TrimEnd(' ').Split(' ');
                        var dd = new List<float>();
                        foreach (string t1 in s)
                        {
                            
                            tempd += Convert.ToDouble(t1.Replace('.', ','));
                            dd.Add((float)Convert.ToDouble(t1.Replace('.', ',')));
                        }
                        suml.Add((float)tempd);
                        d.Add(dd);
                    }
                    double count = d.Count;
                    for (int i = 1; i < d.Count; i++)
                    {
                        count += i;
                    }

                    var del = new bool[d.Count];
               
                    var p = 1;
                    var ddd = 0;
                    double ind = 0;
                    for (var i = 0; i < d.Count - 1; i++)
                    {

                        if (!del[i])
                            Parallel.For(i + 1, d.Count, j =>
                            {

                                //   for (var j = i + 1; j < d.Count; j++)
                                if (!del[j] && Math.Abs(suml[i] - suml[j]) < t)
                                {
                                    double r = 0;
                                    for (var k = 0; k < d[i].Count; k++)
                                    {
                                        r += Math.Abs(d[i][k] - d[j][k]);
                                        if (r > t)
                                        {
                                            break;
                                        }
                                    }
                                    if (r < t)
                                    {
                                        lock (o)
                                        {
                                            if (!del[j])
                                            {
                                                del[j] = true;
                                                ddd++;
                                            }
                                        }

                                    }
                                }
                            });

                        ind += (d.Count - i);
                        if (i % 1000 == 0)
                        {
                            SetText(file+ " "+ddd);
                            Progress(Convert.ToInt32(ind / count * 100));
                        }
                    }


                var    _dateBinForFann =
                      new FileStream(file + "d",
                          FileMode.OpenOrCreate, FileAccess.ReadWrite);   
                              _dateBinForFann.Seek(0, SeekOrigin.End);
                    AddText(_dateBinForFann,
                        Convert.ToString((d.Count-ddd)) + " " + b[1].Split(' ').Count() + " " + b[2].Split(' ').Count());
                    List<int> sort = new List<int>();
                    for (int i = 0; i < del.Length; i++)
                    {
                        sort.Add(i);
                    }
                    Random random = new Random();
                    sort.Sort((t1, t2) => random.Next().CompareTo(random.Next()));
                    for (int i = 0; i < del.Count(); i++)
                    {
                        if (!del[sort[i]])
                        {
                            AddText(_dateBinForFann, b[sort[i]*2+1]);
                            AddText(_dateBinForFann, b[sort[i] * 2 + 2]);
                        }
                    }
                    _dateBinForFann.Close();

                 
                 
                    listBox1.Items.Add (" File save " + file + "d" +  " count clone "+ddd);
                }
            }
        }

        private object o = new object();
        private static void AddText(FileStream fs, string value)
        {
            var info = new UTF8Encoding(true).GetBytes(value + "\r\n");
            fs.Write(info, 0, info.Length);
            fs.Flush();
        }


        #region Callback
        delegate void SetTextCallback(string value);
        delegate void ProgressCallback(int value);
        delegate void ProgressVisibleCallback(bool value);
        private void Progress(int value)
        {
            if (progressBar1.InvokeRequired && progressBar1.InvokeRequired)
            {
                var d = new ProgressCallback(Progress);
                Invoke(d, new object[] { value });
            }
            else
            {

                progressBar1.Visible = Visible;
                progressBar1.Value = value;
                progressBar1.Refresh();
            }
        }
        private void ProgressVisible(bool value)
        {
            if (progressBar1.InvokeRequired && progressBar1.InvokeRequired)
            {
                var d = new ProgressVisibleCallback(ProgressVisible);
                Invoke(d, new object[] { value });
            }
            else
            {

                progressBar1.Visible = value;
                progressBar1.Refresh();

            }
        }

        private void SetText(string value)
        {
            if (label1.InvokeRequired && label1.InvokeRequired)
            {
                var d = new SetTextCallback(SetText);
                Invoke(d, new object[] { value });
            }
            else
            {

                label1.Text = value;
                label1.Refresh();

            }
        }

        #endregion

        private void button2_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                foreach (var file in openFileDialog1.FileNames)
                {

                    var all = File.ReadAllLines(file).ToList();
                    var inp = new List<string>();
                    var outp = new List<string>();
                    for(int i=1;i<all.Count; i++)
                        if (i%2 == 1)
                            inp.Add(all[i]);
                        else
                            outp.Add(all[i]);
                    File.WriteAllLines(
                        Path.GetDirectoryName(file) + "\\" + Path.GetFileNameWithoutExtension(file) + " input" + ".dat",
                        inp);
                    File.WriteAllLines(
                   Path.GetDirectoryName(file) + "\\" + Path.GetFileNameWithoutExtension(file) + " output" + ".dat",
                   outp);

                }
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                foreach (var file in openFileDialog1.FileNames)
                {

                    var b = File.ReadAllLines(file);
                    for (int i = 2; i < b.Length; i += 2)
                    {
                        b[i]= b[i].Replace("0", "-1");
                    }
                    File.WriteAllLines(file + "t", b);
                }
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                foreach (var file in openFileDialog1.FileNames)
                {

                    var b = new List<string>();
                    var d = new List<List<float>>();
                    var suml = new List<float>();
                    var temp = new UTF8Encoding(true);

                    b = File.ReadAllLines(file).ToList();

                    double t = Convert.ToDouble(textBox36.Text);

                    //  Parallel.For(0, date.Count - 2, i =>
                    for (var i = 1; i < b.Count; i += 2)
                    {
                        double tempd = 0;
                        var s = b[i].TrimEnd(' ').Split(' ');
                        var dd = new List<float>();
                        foreach (string t1 in s)
                        {

                            tempd += Convert.ToDouble(t1.Replace('.', ','));
                            dd.Add((float)Convert.ToDouble(t1.Replace('.', ',')));
                        }
                        suml.Add((float)tempd);
                        d.Add(dd);
                    }
                    double count = d.Count;
                    for (int i = 1; i < d.Count; i++)
                    {
                        count += i;
                    }

                    var del = new bool[d.Count];

                    var p = 1;
                    var ddd = 0;
                    double ind = 0;
                    for (var i = 0; i < d.Count - 1; i++)
                    {

                        if (!del[i])
                            Parallel.For(i + 1, d.Count, j =>
                            {

                                //   for (var j = i + 1; j < d.Count; j++)
                                if (!del[j] && Math.Abs(suml[i] - suml[j]) < t)
                                {
                                    double r = 0;
                                    for (var k = 0; k < d[i].Count; k++)
                                    {
                                        r += Math.Abs(d[i][k] - d[j][k]);
                                        if (r > t)
                                        {
                                            break;
                                        }
                                    }
                                    if (r < t)
                                    {
                                        lock (o)
                                        {
                                            if (!del[j])
                                            {
                                                del[j] = true;
                                                ddd++;
                                            }
                                        }

                                    }
                                }
                            });

                        ind += (d.Count - i);
                        if (i % 1000 == 0)
                        {
                            SetText(file + " " + ddd);
                            Progress(Convert.ToInt32(ind / count * 100));
                        }
                    }


                    var _dateBinForFann =
                          new FileStream(file + "d",
                              FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    _dateBinForFann.Seek(0, SeekOrigin.End);

                    var _ValidateBinForFann =
                    new FileStream(file + "v",
                        FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    _ValidateBinForFann.Seek(0, SeekOrigin.End);

                    
                    List<int> sort1 = new List<int>();
                    List<int> sort2 = new List<int>();
                    for (int i = 0; i < del.Length; i++)
                    {
                       if (!del[i])
                        if (i%20 == 0)
                            sort2.Add(i);
                        else
                        sort1.Add(i);
                    }
                    AddText(_dateBinForFann,
                        Convert.ToString((sort1.Count)) + " " + b[1].Split(' ').Count() + " " + b[2].Split(' ').Count());
                    AddText(_ValidateBinForFann,
                        Convert.ToString((sort2.Count)) + " " + b[1].Split(' ').Count() + " " + b[2].Split(' ').Count());
                    Random random = new Random();
                    sort1.Sort((t1, t2) => random.Next().CompareTo(random.Next()));
                    sort2.Sort((t1, t2) => random.Next().CompareTo(random.Next()));
                    for (int i = 0; i < sort1.Count(); i++)
                    {
                       

                            AddText(_dateBinForFann, b[sort1[i] * 2 + 1]);
                            AddText(_dateBinForFann, b[sort1[i] * 2 + 2]);
                        
                    }
                    _dateBinForFann.Close();

                    for (int i = 0; i < sort2.Count(); i++)
                    {
                      

                            AddText(_ValidateBinForFann, b[sort2[i] * 2 + 1]);
                            AddText(_ValidateBinForFann, b[sort2[i] * 2 + 2]);
                        
                    }
                    _ValidateBinForFann.Close();


                    listBox1.Items.Add(" File save " + file + "d" + " count clone " + ddd);
                }
            }
        }
    }
}
